// Copyright (c) 2023 Presto Labs Pte. Ltd.
// Author: tianqiang

#include "coin2/exchange/bitmart/api_order/native_rest_async_asio_subscriber.h"

namespace coin2::exchange::bitmart::api_order {

void BitmartRestAsyncAsioSubscriber::QueryAccountBalance() {
  RestParams params;
  auto http_context = rest_client()->QueryAccountBalance();
  if (!http_context) {
    return;
  }
  http_context->handler =
      std::bind(&BitmartRestAsyncAsioSubscriber::HandleQuery, this, std::placeholders::_1);
  http_driver_->PostAsyncContext(http_context);
}

void BitmartRestAsyncAsioSubscriber::QueryOpenOrders(
    const std::string& native_symbol,
    int64_t end_time) {
  RestParams params;
  params.set_symbol(native_symbol);
  auto http_context = rest_client()->QueryOpenOrders(params, end_time);
  if (!http_context) {
    return;
  }
  http_context->handler =
      std::bind(&BitmartRestAsyncAsioSubscriber::HandleQuery, this, std::placeholders::_1);
  http_driver_->PostAsyncContext(http_context);
}

void BitmartRestAsyncAsioSubscriber::QueryHistoryOrders(const std::string& native_symbol) {
  RestParams params;
  params.set_symbol(native_symbol);
  auto http_context = rest_client()->QueryHistoryOrders(params);
  if (!http_context) {
    return;
  }
  http_context->handler =
      std::bind(&BitmartRestAsyncAsioSubscriber::HandleQuery, this, std::placeholders::_1);
  http_driver_->PostAsyncContext(http_context);
}

void BitmartRestAsyncAsioSubscriber::QueryFills(const std::string& native_symbol) {
  RestParams params;
  params.set_symbol(native_symbol);
  auto http_context = rest_client()->QueryFills(params);
  if (!http_context) {
    return;
  }
  http_context->handler =
      std::bind(&BitmartRestAsyncAsioSubscriber::HandleQuery, this, std::placeholders::_1);
  http_driver_->PostAsyncContext(http_context);
}

void BitmartRestAsyncAsioSubscriber::SubscribeAsync() {
  AddPeriodicTask(
      std::bind(&BitmartRestAsyncAsioSubscriber::QueryAccountBalance, this),
      config_.query_account_balance_period_sec(),
      "query_balance");

  const auto symbol_list = native_symbols();

  AddPeriodicTask(
      std::bind(&BitmartRestAsyncAsioSubscriber::QueryOpenOrders, this, std::placeholders::_1, 0),
      config_.query_open_orders_period_sec(),
      "query_open_orders",
      symbol_list);

  AddPeriodicTask(
      std::bind(&BitmartRestAsyncAsioSubscriber::QueryHistoryOrders, this, std::placeholders::_1),
      config_.query_cancel_orders_period_sec(),
      "query_history_orders",
      symbol_list);

  AddPeriodicTask(
      std::bind(&BitmartRestAsyncAsioSubscriber::QueryFills, this, std::placeholders::_1),
      config_.query_fill_period_sec(),
      "query_fills",
      symbol_list);

  // handle open order more than one page
  mb_->Subscribe("bitmart_spot/query_open_orders", [this](const std::string&, void* data) {
    std::pair<std::string, int64_t> symbol_and_end_time(
        *static_cast<std::pair<std::string, int64_t>*>(data));

    LOG(INFO) << "bitmart_spot/query_open_orders symbol:" << symbol_and_end_time.first
              << " end_time:" << symbol_and_end_time.second;

    QueryOpenOrders(symbol_and_end_time.first, symbol_and_end_time.second);
  });
}

}  // namespace coin2::exchange::bitmart::api_order
